package cn.com.jonpad.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;

import static cn.com.jonpad.config.Resources.DEMO_RESOURCE_ID;

/**
 * @author Jon Chan
 * @date 2018/9/12 14:32
 */
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfigurer extends AuthorizationServerConfigurerAdapter {
	@Autowired
	AuthenticationManager authenticationManager;
	@Autowired
	RedisConnectionFactory redisConnectionFactory;

	/**
	 * client指示的是 受信任的第三方调用者，并且配置受信任的调用者基本信息
	 * @param clients
	 * @throws Exception
	 */
	@Override
	public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
		//配置两个客户端,一个用于password认证一个用于client认证
		clients.inMemory().withClient("client_1")
				.resourceIds(DEMO_RESOURCE_ID)
				.authorizedGrantTypes("client_credentials", "refresh_token")
				.scopes("select")
				.authorities("client")
				.secret("123456")
				.and().withClient("client_2")
				.resourceIds(DEMO_RESOURCE_ID)
				.authorizedGrantTypes("password", "refresh_token")
				.scopes("select")
				.authorities("client")
				.secret("123456");
	}

	/**
	 * 用来配置授权（authorization）以及令牌（token）的访问端点和令牌服务(token services)。
	 * @param endpoints
	 * @throws Exception
	 */
	@Override
	public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
		endpoints
				.tokenStore(new RedisTokenStore(redisConnectionFactory))
				.authenticationManager(authenticationManager);
	}

	/**
	 * 用来配置令牌端点(Token Endpoint)的安全约束.
	 * @param oauthServer
	 * @throws Exception
	 */
	@Override
	public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
		//允许表单认证
		oauthServer.allowFormAuthenticationForClients();
	}
}
